package com.example.myapplication;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;

import androidx.annotation.RequiresApi;

import com.alibaba.fastjson.JSON;
import com.example.myapplication.bean.FaceBean;
import com.example.myapplication.bean.LoadImageBean;
import com.example.myapplication.net.Common;
import com.example.myapplication.utils.OkHttp3_0Utils;
import com.example.myapplication.utils.QZXTools;
import com.example.myapplication.utils.SharedPreferenceUtil;
import com.example.myapplication.utils.ThreadPool;
import com.hjq.toast.ToastUtils;
import com.sanstar.baiduFacePay.BaiduFacePay;
import com.sanstar.baiduFacePay.callback.IBaiduFaceCB;

import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

import static com.example.myapplication.net.Common.BaseUrl;

public class LoadImageActivity extends BaseActivity {

    private final static String TAG = "LoadImageActivity";

    MyHandler mHandler;

    HashMap<String, Object> map = new HashMap<>();
    public  boolean initFace = false;
    private Integer currentPage = 1;
    private Integer totalPage = 1;
    private Integer pageSize = 50;
    private TextView tv_name;

    private class MyHandler extends Handler {
        private WeakReference<Activity> activityWeakReference;
        public MyHandler(Activity activity) {
            activityWeakReference = new WeakReference<>(activity);
        }
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Activity activity = activityWeakReference.get();
            Log.d(TAG, "msg = " + msg.what);
            if (activity != null) {
                switch (msg.what) {
                    case 1:
                        BaiduFacePay.getInstance().preloadSdkEnv(map, new IBaiduFaceCB() {
                            @Override
                            public void response(Map info) {
                                String msg = (String) info.get("return_msg");
                                int code = (int) info.get("return_code");
                                Log.d(TAG, "preloadSdkEnv msg = " + msg + ", code = " + code);
                                if (msg.equals("SUCC")) {
                                    mHandler.sendEmptyMessage(2);
                                    initFace = true;
                                    baseHandler.postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            tv_name.append("百度人脸识别初始化成功\n");
                                            //开始定时任务
                                            timer();
                                        }
                                    },1000);


                                }
                            }
                        });
                        break;
                    case 2:
                        BaiduFacePay.getInstance().manualUpdateFaceData(map, new IBaiduFaceCB() {
                            @Override
                            public void response(Map map) {
                                String msg = (String) map.get("return_msg");
                                int code = (int) map.get("return_code");
                                Log.d(TAG, "manualUpdateFaceData msg = " + msg + ", code = " + code);
                                if (msg.equals("SUCC")) {
                                    mHandler.sendEmptyMessage(3);
                                }
                            }
                        });
                        break;
                    case 3:
//                        Intent intent = new Intent();
//                        intent.setClass(LoadImageActivity.this, CameraTestActivity.class);
//                        startActivity(intent);


                        //Intent intent = new Intent();
                        //intent.setClass(MainActivity.this, AddFaceActivity.class);
                        //startActivity(intent);

                        //获取特征值
                        //  startLoadImage();

                        break;
                    default:
                        break;
                }
            }
        }
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_load_image);
        tv_name = findViewById(R.id.tv_name);

        startImage = 0;
        mHandler = new MyHandler(this);

        //下载图片到本地
        findViewById(R.id.down_image).setOnClickListener((view) -> {



            BaiduFacePay.getInstance().initBaiduFace(this, map, new IBaiduFaceCB() {

                @Override
                public void response(Map info) {
                    if (info == null) {
                        new RuntimeException("调用返回为空").printStackTrace();
                        return;
                    }
                    String msg = (String) info.get("return_msg");
                    int code = (int) info.get("return_code");
                    if (msg == null || !msg.equals("SUCC")) {
                        new RuntimeException("调用返回非成功信息：" + msg).printStackTrace();
                    }
                    Log.d("app", "init msg = " + msg + ", code = " + code);
                    mHandler.sendEmptyMessage(1);
                }
            });

        });



    }


    private void deleteFile(){
        startImage = 0;
        //删除本地文件
        File appDir = new File(Environment.getExternalStorageDirectory(), "tiantian");
        if (appDir.exists()){
            QZXTools.deleteFile(appDir);
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    tv_name.append("删除本地要保存的图片文件\n");
                }
            },1000*60);

        }
    }


    @Override
    protected void handleActMessage(Message msg) {
        super.handleActMessage(msg);
        switch (msg.what) {
            case Common.Interface_err:
                String info = (String) msg.obj;
                   ToastUtils.show(info);
                //显示 没有授权
               // MessageDialog.show("标题", info, "确定");
                break;
            case Common.Interface_success:
                LoadImageBean adviceActivationBean = (LoadImageBean) msg.obj;;
                LoadImageBean.DataDTO dataDTO = adviceActivationBean.getData();
                if (dataDTO!=null){
                    List<LoadImageBean.DataDTO.RecordsDTO> records = dataDTO.getRecords();
                    //获取当前页
                    currentPage = dataDTO.getCurrent();
                    totalPage = dataDTO.getTotal();
                    baseHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            tv_name.append("分页加载，当前页currentPage=" + currentPage+"\n");
                            tv_name.append("一共多少页="+ totalPage+"\n");
                            tv_name.append("当前页要处理图片的个数="+ records.size()+"\n");

                            if (records!=null && records.size() >0){
                                //开始处理图片
                                startProcessPictures(records);
                            }
                        }
                    },1000);



                }

//                String deviceSn = dataDTO.getDeviceSn();
//                String accessKey = dataDTO.getAccessKey();
//                SharedPreferenceUtil.getInstance(MyAPP.getInstance()).setString("deviceSn",deviceSn);
//                SharedPreferenceUtil.getInstance(MyAPP.getInstance()).setString("accessKey",accessKey);
//
//                //已经授权了进入客屏和主屏
//                Intent intent = new Intent(this, GuestScreenActivity.class);
//                startActivity(intent);
             //   finish();
                break;

        }
    }

    /**
     * 开始处理图片
     * @param records
     */
    private void startProcessPictures(List<LoadImageBean.DataDTO.RecordsDTO> records) {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                tv_name.append("把图片下载保存到本地\n");
                startImage =0;
                ThreadPool.singleExecute(new Runnable() {
                    @Override
                    public void run() {
                        for (LoadImageBean.DataDTO.RecordsDTO record : records) {
                            //拿到图片保存到本地
                            try {
                                Thread.sleep(4000);
                                loadImageToLocal(record,records.size());
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }

                        }
                    }
                });

            }
        },5000);
    }

    //下载图片
    private void downFaceImage() {
        String url = Common.DOWN_FACE_IMAGE;
        currentPage = SharedPreferenceUtil.getInstance(MyAPP.getInstance()).getInt("currentPage",1);
        Map<String, String> mapParams = new LinkedHashMap<>();
        mapParams.put("page", currentPage+"");
        mapParams.put("size", pageSize +"");
//        Map<String,String> headerParams = new LinkedHashMap<>();
//        String token = SharedPreferenceUtil.getInstance(MyAPP.getInstance()).getString("token");
//        headerParams.put("Authorization","Bearer " + token);

        OkHttp3_0Utils.getInstance().asyncGetOkHttp(url, mapParams,  new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Message message = Message.obtain();
                message.what = Common.Interface_err;
                message.obj = "当前服务不可用";
                baseHandler.sendMessage(message);

                baseHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        tv_name.append("当前服务不可用\n");
                    }
                },1000);
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String content = response.body().string();
                QZXTools.logE("onResponse: " + content, null);

                JSONObject jsonObject = null;
                try {
                    jsonObject = new JSONObject(content);
                    int code = jsonObject.optInt("code");
                    String msg = jsonObject.optString("message");
                    if (code == 200) {
                        LoadImageBean loadImageBean = JSON.parseObject(content, LoadImageBean.class);
                        Message message = Message.obtain();
                        message.what = Common.Interface_success;
                        message.obj = loadImageBean;
                        baseHandler.sendMessage(message);
                    } else {
                        Message message = Message.obtain();
                        message.what = Common.Interface_err;
                        message.obj = msg;
                        baseHandler.sendMessage(message);
                    }
                } catch (Exception e) {
                    Message message = Message.obtain();
                    message.what = Common.Interface_err;
                    message.obj = "当前服务获取数据失败";
                    baseHandler.sendMessage(message);
                }
            }
        });

    }
    //当前要处理的图片是 一来时 是0
    private volatile int startImage = 0;

    private synchronized void loadImageToLocal(LoadImageBean.DataDTO.RecordsDTO record, int size) {

        String imageUrl = record.getImageUrl();
        Integer memberId = record.getMemberId();
        String currentImageUrl = BaseUrl + imageUrl;
        //下载图片到本地
        //1 先下载 50张图片 处理生成 特征码,成功后再下载 第2个50张图片 ，处理生成特征码
        //2 把下载的图片保存到本地
        OkHttp3_0Utils.getInstance().asycPostImageOkhttp(currentImageUrl, null, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    baseHandler.post(new Runnable() {
                        @Override
                        public void run() {

                            baseHandler.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    tv_name.append("当前服务不可用\n");
                                }
                            },1000);
                        }
                    });
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                //获取流
                InputStream inputStream = response.body().byteStream();
                //转化为bitmap
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                onSaveBitmap(bitmap,LoadImageActivity.this,String.valueOf(memberId));
                ++startImage;

                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        tv_name.append("当前正在保存的图片startImage=" + startImage +"\n");
                    }
                });

                //说明当天图片下载完成了
                if (startImage == size){
                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            tv_name.append("下载的图片保存到本地完成\n");
                            downloadCompleted();
                        }
                    },1000);
                }

            }
        });
    }



    public void timer(){
        //开始线程25分钟定时下载数据
        ThreadPool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                //提交下一页数据
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        deleteFile();
                    }
                });

                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        currentPage = SharedPreferenceUtil.getInstance(MyAPP.getInstance()).getInt("currentPage",1);
                        tv_name.append("/////////////////////////////////////////////////////////////////\n");
                        tv_name.append("/////////////////////////////////////////////////////////////////\n");

                        tv_name.append("延时20分钟后定时下载第" + currentPage +"页的数据\r\n");

                        downFaceImage();
                    }
                },1000 * 70);

            }
        });
    }


    /*
   Android保存图片到系统图库：http://blog.csdn.net/xu_fu/article/details/39158747
   * */
    private void onSaveBitmap(final Bitmap mBitmap, final Context context,String patch) {

        // 第一步：首先保存图片
        //将Bitmap保存图片到指定的路径/sdcard/Boohee/下，文件名以当前系统时间命名,但是这种方法保存的图片没有加入到系统图库中
        File appDir = new File(Environment.getExternalStorageDirectory(), "tiantian");

        if (!appDir.exists()) {
            appDir.mkdir();
        }

        String fileName = patch+ ".jpg";
        File file = new File(appDir, fileName);

        try {
            FileOutputStream fos = new FileOutputStream(file);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 第二步：其次把文件插入到系统图库
//        try {
//            MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null);
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        }
//
//        // 第三步：最后通知图库更新
//        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file)));
//        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
    }



    //当前图片下载完成
    private void downloadCompleted() {
        baseHandler.postDelayed(() -> {
            tv_name.append("开始处理把图片生成特征码\n");
            //开始处理把图片生成特征码
            startFeatureCode();

        },5000);

    }
    //开始生成成特征码
    private void startFeatureCode() {
        faceBeanList.clear();
        File appDir = new File(Environment.getExternalStorageDirectory(), "tiantian");
        List<String> filesAllName = QZXTools.getFilesAllName(appDir);
        Log.i(TAG, "startFeatureCode: "+filesAllName);
        //

        if (initFace){
            ThreadPool.singleExecute(new Runnable() {
                @Override
                public void run() {
                    for (String path : filesAllName) {
                        try {
                            Thread.sleep(100);
                            startLoadImage(path,filesAllName.size());
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }


                }
            });




        }else {
            baseHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    tv_name.append("人脸识别初始化失败\n");
                }
            },1000);
        }
    }

    private volatile   List<FaceBean> faceBeanList = new ArrayList<>();
    // todo 要是处理失败也要处理
    private List<String> unDeals = new ArrayList<>();
    private synchronized void startLoadImage(String path, int size) {
        HashMap<String, Object> map = new HashMap<>();
        //   map.put("pictureURL", "/sdcard/tiantianqin.jpg");
        map.put("pictureURL",path);
        QZXTools.logD(TAG +"path=" +path);
        BaiduFacePay.getInstance().getFaceFeature(map, new IBaiduFaceCB() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void response(Map map) {
                String msg = (String) map.get("return_msg");
                int code = (int) map.get("return_code");
                byte[] feature = (byte[]) map.get("feature");
                Log.d(TAG, "get feature msg = " + msg + ", code = " + code);

                if (feature!=null){
                    Log.d(TAG, "feature = " + Base64.getEncoder().encodeToString(feature));
                    int index = path.lastIndexOf("/");
                    String currentPath = path.substring(index+1,path.length()-4);

                    Log.d(TAG, "response: currentPath=" + currentPath);
                    FaceBean faceBean = new FaceBean();
                    faceBean.setFeatureData(Base64.getEncoder().encodeToString(feature));
                    faceBean.setMemberId(Integer.valueOf(currentPath));
                    faceBeanList.add(faceBean);
                    //合法的和不合法的都一起提交 把不合法的记录下来
                    if (faceBeanList.size() + unDeals.size()  == size){
                        mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                tv_name.append("特征值生成完成 上传服务器\n");
                                //shengcheng特征值完成 上传服务器
                                eigenvaluesCompleted(faceBeanList);
                            }
                        },1000);
                        startImage = 0;

                    }
                }else {
                    int index = path.lastIndexOf("/");
                    String currentPath = path.substring(index+1,path.length()-4);
                    unDeals.add(currentPath);

                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            tv_name.append("生成特征码失败当前id=" + currentPath+"\n");
                            startImage = 0;
                        }
                    },1000);
                }
            }
        });


    }

    /**
     * 生成特征值完成
     * @param faceBeanList
     */
    private void eigenvaluesCompleted(List<FaceBean> faceBeanList) {
        String url = Common.UPDATA_FACE_IMAGE;
        try {
            JSONArray jsonArray = new JSONArray();

            for (FaceBean faceBean : faceBeanList) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("memberId",faceBean.getMemberId()+"");
                jsonObject.put("featureData",faceBean.getFeatureData());

                jsonArray.put(jsonObject);
            }


            OkHttp3_0Utils.getInstance().asyncJsonOkHttp(url, jsonArray, new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    Message message = Message.obtain();
                    message.what = Common.Interface_err;
                    message.obj = "当前服务不可用";
                    baseHandler.sendMessage(message);
                }

                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                    String content = response.body().string();
                    QZXTools.logE("onResponse: " + content, null);

                    JSONObject jsonObject = null;
                    try {
                        jsonObject = new JSONObject(content);
                        int code = jsonObject.optInt("code");
                        String msg = jsonObject.optString("message");
                        if (code == 200) {
                            //提交到服务器成功后,获取下一条
                            if (currentPage < totalPage){
                                currentPage++;
                                SharedPreferenceUtil.getInstance(MyAPP.getInstance()).setInt("currentPage",currentPage);

                            }
                        } else {
                            Message message = Message.obtain();
                            message.what = Common.Interface_err;
                            message.obj = msg;
                            baseHandler.sendMessage(message);
                        }
                    } catch (Exception e) {
                        Message message = Message.obtain();
                        message.what = Common.Interface_err;
                        message.obj = "当前服务获取数据失败";
                        baseHandler.sendMessage(message);
                    }
                }
            });
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        ThreadPool.closeExecute();
    }
}
